package com.iqiyi.pps.epg.core.service.auth;


import com.iqiyi.pps.epg.core.dao.auth.AuthorityDao;
import com.iqiyi.pps.epg.core.dao.auth.ResourceDao;
import com.iqiyi.pps.epg.core.dao.auth.RoleDao;
import com.iqiyi.pps.epg.core.dao.auth.SysUserDao;
import com.iqiyi.pps.epg.core.dao.base.Page;
import com.iqiyi.pps.epg.core.dao.base.PropertyFilter;
import com.iqiyi.pps.epg.core.exception.ServiceException;
import com.iqiyi.pps.epg.core.infrastructure.log.LoggerBuilder;
import com.iqiyi.pps.epg.core.model.auth.Authority;
import com.iqiyi.pps.epg.core.model.auth.Resource;
import com.iqiyi.pps.epg.core.model.auth.Role;
import com.iqiyi.pps.epg.core.model.auth.SysUser;
import com.iqiyi.pps.epg.core.utils.Constants;
import com.iqiyi.pps.epg.core.utils.SpringSecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 系统用户业务类
 */
@Component
@Transactional
public class SysUserManager {

	private static Logger logger = LoggerFactory.getLogger(SysUserManager.class);

    @Autowired
	private SysUserDao userDao;
    @Autowired
	private RoleDao roleDao;
    @Autowired
	private AuthorityDao authorityDao;
    @Autowired
    private ResourceDao resourceDao;

    /**
     * 根据ID取系统用户对象
     * @param id  主键ID
     * @return  SysUser
     */
	@Transactional(readOnly = true)
	public SysUser getUser(Long id) {
		return userDao.get(id);
	}

    /**
     * 更新或插入系统用户对象
     * @param entity 系统用户对象
     */
	public void saveUser(SysUser entity) {
        LoggerBuilder loggerBuilder = new LoggerBuilder("sysuser", "save", "in", "user", entity.getLoginName());
        logger.info(loggerBuilder.format(), loggerBuilder.getParams());
        long start = System.currentTimeMillis();
        userDao.save(entity);

        long end = System.currentTimeMillis();

        loggerBuilder.clear().setStep("saved").put("time(ms)", (end - start));
        logger.info(loggerBuilder.format(), loggerBuilder.getParams());

        loggerBuilder.setStep("out");
        logger.info(loggerBuilder.format(), loggerBuilder.getParams());
	}

	/**
	 * 删除用户,如果尝试删除超级管理员将抛出异常.
     * @param id 主键ID
	 */
	public void deleteUser(Long id) {
		if (isSupervisor(id)) {
			logger.warn("操作员{}尝试删除超级管理员用户", SpringSecurityUtils.getCurrentUserName());
			throw new ServiceException("不能删除超级管理员用户");
		}
		userDao.delete(id);
	}

    /**
     * 根据角色id取出.
     * @param id 主键ID
     */
    public List<SysUser> listUserByRoleId(Long id) {
       return  roleDao.listUserByRoleId(id);
    }

	/**
	 * 判断是否超级管理员.
     * @param id 用户主键ID
     * @return true：超级管理员，false：非超级管理员
	 */
	private boolean isSupervisor(Long id) {
		return id == Constants.SUPER_ADMIN_ID;
	}

    /**
     * 判断是否管理员.
     * @param userId 用户主键ID
     * @return true：管理员，false：非管理员
     */
    public boolean isAdmin(Long userId) {
        SysUser user = userDao.get(userId);
        if(user != null) {
            return user.getRoleIds().contains(Constants.ROLE_ADMIN);
        }
        return false;
    }

    /**
	 * 使用属性过滤条件查询用户.
     * @param page Page<SysUser>
     * @param filters 过滤条件
     * @return Page<SysUser>
	 */
	@Transactional(readOnly = true)
	public Page<SysUser> searchUser(final Page<SysUser> page, final List<PropertyFilter> filters) {
		return userDao.findPage(page, filters);
	}

    /**
     * 根据登录名查询系统用户
     * @param loginName 登录名
     * @return SysUser
     */
	@Transactional(readOnly = true)
	public SysUser findUserByLoginName(String loginName) {
		return userDao.findUniqueBy("loginName", loginName);
	}

	/**
	 * 检查用户名是否唯一.
	 * @param newLoginName 新的登录名
     * @param oldLoginName 旧的登录名
	 * @return loginName在数据库中唯一或等于oldLoginName时返回true.
	 */
	@Transactional(readOnly = true)
	public boolean isLoginNameUnique(String newLoginName, String oldLoginName) {
		return userDao.isPropertyUnique("loginName", newLoginName, oldLoginName);
	}

    /**
	 * 检查用角色是否唯一.
     * @param newRoleName  新的角色名
     * @param oldRoleName  旧的角色名
	 * @return RoleName在数据库中唯一或等于oldRoleName时返回true.
	 */
	@Transactional(readOnly = true)
	public boolean isRoleNameUnique(String newRoleName, String oldRoleName) {
		return roleDao.isPropertyUnique("name", newRoleName, oldRoleName);
	}

    /**
     * 根据主键取角色对象
     * @param id 主键ID
     * @return Role
     */
	@Transactional(readOnly = true)
	public Role getRole(Long id) {
		return roleDao.get(id);
	}

    /**
     * ID升序的方式取出所有角色
     * @return List<Role>
     */
	@Transactional(readOnly = true)
	public List<Role> getAllRole() {
		return roleDao.getAll("id", true);
	}

    /**
     * 保存角色对象
     * @param entity 角色对象
     */
	public void saveRole(Role entity) {
		roleDao.save(entity);
	}

    /**
     * 根据主键ID删除角色
     * @param id  主键ID
     */
	public void deleteRole(Long id) {
		roleDao.delete(id);
	}

    /**
     * 取出所有权限
     * @return List<Authority>
     */
	@Transactional(readOnly = true)
	public List<Authority> getAllAuthority() {
		return authorityDao.getAll();
	}

    @Transactional(readOnly = true)
    public List<Resource> getUrlResourceWithAuthorities() {
        return resourceDao.getUrlResourceWithAuthorities();
    }

    /**
     * 根据主键ID取权限对象
     * @param id 主键ID
     * @return Authority
     */
    @Transactional(readOnly = true)
    public Authority getAuthorty(Long id) {
        return authorityDao.get(id);
    }

    public List<SysUser> getUserList() {
        return userDao.getAll();
    }
}
